package com.ship.boats.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ship.boats.business.impl.BoatsSystemServiceImpl;
import com.ship.boats.domain.IhsShipBase;
import com.ship.boats.domain.SpBoatsArchivesExtend;
import com.ship.boats.domain.SpBoatsVoyageMessage;
import com.ship.boats.domain.dto.BoatsPscInspectRq;
import com.ship.boats.domain.dto.BoatsVoyageMessageRq;
import com.ship.boats.domain.dto.QueryBoatsVoyageRq;
import com.ship.boats.domain.dto.QueryPortNameRq;
import com.ship.boats.domain.vo.*;
import com.ship.boats.mapper.BoatsVoyageMessageMapper;
import com.ship.boats.service.BoatsArchivesExtendService;
import com.ship.boats.service.BoatsArchivesService;
import com.ship.boats.service.BoatsVoyageMessageService;
import com.ship.common.core.constant.CacheConstants;
import com.ship.common.core.constant.ShipApiConstants;
import com.ship.common.core.utils.bean.BeanUtils;
import com.ship.common.redis.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.IsoFields;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>BoatsVoyageMessageServiceImpl</b>
 *
 * @description: BoatsVoyageMessageServiceImpl <br>
 * @date: 2024/4/12 16:23 <br>
 * @author: lhm <br>
 * @version: 1.0 <br>
 */

@Service
public class BoatsVoyageMessageServiceImpl extends ServiceImpl<BoatsVoyageMessageMapper, SpBoatsVoyageMessage> implements BoatsVoyageMessageService {
    private static final Logger logger = LoggerFactory.getLogger(BoatsVoyageMessageServiceImpl.class);

    @Autowired
    private BoatsArchivesService boatsArchivesService;

    @Autowired
    private BoatsSystemServiceImpl boatsSystemServiceImpl;

    @Autowired
    private BoatsArchivesExtendService boatsArchivesExtendService;

    @Autowired
    private RedisService redisService;

    @Override
    public void getBoatsVoyageMessage(String startTime1, String endTime1) throws ParseException {
        List<String> imoList = boatsArchivesService.queryImoList();
//        List<String> imoList = new ArrayList<>();
//        imoList.add("7390143");
        if (CollectionUtil.isNotEmpty(imoList)) {
            long startTime = 0;
            long endTime = 0;
            if (StringUtils.isNotEmpty(startTime1) && StringUtils.isNotEmpty(endTime1)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date startDate = sdf.parse(startTime1 + " 00:00:00");
                startTime = startDate.getTime();
                Date endDate = sdf.parse(endTime1 + " 23:59:59");
                endTime = endDate.getTime();
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                calendar.add(Calendar.MONTH, -3);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                Date time = calendar.getTime();
                String date = DateUtil.format(time, DatePattern.NORM_DATE_FORMATTER);
                startTime1 = date;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date startDate = sdf.parse(date + " 00:00:00");
                startTime = startDate.getTime();
                endTime1 = DateUtil.format(new Date(),DatePattern.NORM_DATE_FORMATTER);
                Date endDate = sdf.parse(endTime1 + " 23:59:59");
                endTime = endDate.getTime();
            }
            String startDateStr = startTime1;
            String endDateStr = endTime1;
            long finalEndTime = endTime / 1000;
            long finalStartTime = startTime / 1000;
            //根据时间范围删除数据
            baseMapper.deleteVoyageMessage(startDateStr,endDateStr);
            imoList.forEach(item -> {
                Map<String, String> map = new HashMap<>();
                map.put("imo", item);
                map.put("startTime", String.valueOf(finalStartTime));
                map.put("endTime", String.valueOf(finalEndTime));
                Object data = boatsSystemServiceImpl.getBoatsUtil(map, ShipApiConstants.BOATS_VOYAGE_URL);
                logger.info("查询航次列表返回结果:{}"+JSONUtil.parse(data));
                if (null != data) {
                    List<BoatsVoyageMessageRq> list = JSONUtil.toList(JSONUtil.parseArray(data), BoatsVoyageMessageRq.class);
                    logger.info("查询返回结果:{}"+JSONUtil.parse(list));
                    if (CollectionUtil.isNotEmpty(list)) {
                        List<SpBoatsVoyageMessage> boatsVoyageMessageList = new ArrayList<>();
                        list.forEach(value -> {
//                            if (value.getVoyageStatus().equals("航次进行中")) {
//                            QueryWrapper queryWrapper = new QueryWrapper();
//                            queryWrapper.eq("imo", value.getImo());
//                            queryWrapper.eq("load_port", value.getLoadPort());
//                            queryWrapper.eq("load_inport_time", value.getLoadInportTime());
//                            baseMapper.delete(queryWrapper);
                            SpBoatsVoyageMessage spBoatsVoyageMessage = new SpBoatsVoyageMessage();
                            BeanUtils.copyProperties(value, spBoatsVoyageMessage);
                            spBoatsVoyageMessage.setEnable("1");
                            spBoatsVoyageMessage.setCreateTime(new Date());
                            spBoatsVoyageMessage.setUpdateTime(new Date());
                            boatsVoyageMessageList.add(spBoatsVoyageMessage);
//                            }
                        });
                        this.saveBatch(boatsVoyageMessageList);
                    }
                }
            });
        }
    }

    @Override
    public QueryReceiveCountryInfo queryBoatsVoyageList(QueryBoatsVoyageRq rq) throws IllegalAccessException {
        QueryReceiveCountryInfo queryReceiveCountryInfo = new QueryReceiveCountryInfo();
        if (rq.getPageNum() == 0 || rq.getPageSize() == 0) {
            rq.setPageNum(1);
            rq.setPageSize(10);
        }
        if (CollectionUtil.isNotEmpty(rq.getShipNameList())){
            List<String> imoList = baseMapper.queryImoListByShipName(rq.getShipNameList());
            rq.setShipNameList(null);
            rq.setImoList(imoList);
        }
        PageHelper.startPage(rq.getPageNum(), rq.getPageSize());
        List<QueryBoatsVoyageMessageInfo> voyageMessageList = baseMapper.queryBoatsVoyageList(rq);
        logger.info("查询航次列表信息返回结果:{}"+JSONUtil.parse(voyageMessageList));
        if (CollectionUtil.isNotEmpty(voyageMessageList)) {
            voyageMessageList.forEach(item -> {
                IhsShipBase shipBase = boatsArchivesService.queryShipBaseByImo(item.getImo());
                logger.info("查询船舶信息返回结果:{}"+JSONUtil.parse(shipBase));
                if (null != shipBase) {
                    item.setShipTypeGroup(shipBase.getShipTypeGroup());
                    item.setOperator(shipBase.getOperator());
                }
            });
        }
        PageInfo<QueryBoatsVoyageMessageInfo> pageInfo = new PageInfo<>(voyageMessageList);
        queryReceiveCountryInfo.setPageInfo(pageInfo);
        return queryReceiveCountryInfo;
    }

    public boolean checkDataStatus(QueryBoatsVoyageRq rq) throws IllegalAccessException {
        boolean status = false;
        Class<? extends QueryBoatsVoyageRq> aClass = rq.getClass();
        for (Field field : aClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.get(rq) != null && field.get(rq) != "" && field.get(rq) != "0"){
                status = true;
            }else {
                status = false;
                return status;
            }
        }
        return status;
    }

    @Override
    public QueryReceiveCountryInfo queryDataAnalyze(QueryBoatsVoyageRq rq) throws IllegalAccessException {
        QueryReceiveCountryInfo queryReceiveCountryInfo = new QueryReceiveCountryInfo();

        boolean status = this.checkDataStatus(rq);
        if (status){
            List<QueryDeliverCountryInfo> deliverCountryList = redisService.getCacheObject(CacheConstants.VOYAGE_LIST+"deliverCountry");
            if (CollectionUtil.isNotEmpty(deliverCountryList)){
                queryReceiveCountryInfo.setDeliverCountryList(deliverCountryList);
            }else {
                //统计发货国贸易量
                List<QueryDeliverCountryInfo> loadCountryList = baseMapper.countLoadCountryList(rq);
                if (CollectionUtil.isNotEmpty(loadCountryList)){
                    if (loadCountryList.size() > 10){
                        List<QueryDeliverCountryInfo> ruletList = loadCountryList.stream().limit(10).collect(Collectors.toList());
                        QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
                        queryDeliverCountryInfo.setCountryName("others");
                        Integer total = 0;
                        for (int i = 10; i < loadCountryList.size(); i++) {
                            total = total + loadCountryList.get(i).getTotalCargoProspect();
                        }
                        queryDeliverCountryInfo.setTotalCargoProspect(total);
                        ruletList.add(queryDeliverCountryInfo);
                        queryReceiveCountryInfo.setDeliverCountryList(ruletList);
                        //刷新缓存信息
                        redisService.setCacheObject(CacheConstants.VOYAGE_LIST+"deliverCountry"
                                ,ruletList,CacheConstants.DATA_BOARD_REFRESH_TIME, TimeUnit.MINUTES);
                    }else {
                        queryReceiveCountryInfo.setDeliverCountryList(loadCountryList);
                        //刷新缓存信息
                        redisService.setCacheObject(CacheConstants.VOYAGE_LIST+"deliverCountry"
                                ,loadCountryList,CacheConstants.DATA_BOARD_REFRESH_TIME, TimeUnit.MINUTES);
                    }
                }
            }
            List<QueryDeliverCountryInfo> voyageCountryList = redisService.getCacheObject(CacheConstants.VOYAGE_LIST+"voyageCountry");
            if (CollectionUtil.isNotEmpty(voyageCountryList)){
                queryReceiveCountryInfo.setVoyageCountryList(voyageCountryList);
            }else {
                //统计收货国
                List<QueryDeliverCountryInfo> dischargeCountryList = baseMapper.countDischargeCountryList(rq);
                if (CollectionUtil.isNotEmpty(dischargeCountryList)){
                    if (dischargeCountryList.size() > 10){
                        List<QueryDeliverCountryInfo> ruletList = dischargeCountryList.stream().limit(10).collect(Collectors.toList());
                        QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
                        queryDeliverCountryInfo.setCountryName("others");
                        Integer total = 0;
                        for (int i = 10; i < dischargeCountryList.size(); i++) {
                            total = total + dischargeCountryList.get(i).getTotalCargoProspect();
                        }
                        queryDeliverCountryInfo.setTotalCargoProspect(total);
                        ruletList.add(queryDeliverCountryInfo);
                        queryReceiveCountryInfo.setVoyageCountryList(ruletList);
                        //刷新缓存信息
                        redisService.setCacheObject(CacheConstants.VOYAGE_LIST+"voyageCountry"
                                ,ruletList,CacheConstants.DATA_BOARD_REFRESH_TIME, TimeUnit.MINUTES);
                    }else {
                        queryReceiveCountryInfo.setVoyageCountryList(dischargeCountryList);
                        //刷新缓存信息
                        redisService.setCacheObject(CacheConstants.VOYAGE_LIST+"voyageCountry"
                                ,dischargeCountryList,CacheConstants.DATA_BOARD_REFRESH_TIME, TimeUnit.MINUTES);
                    }
                }
            }
        }else {
            //统计发货国贸易量
            List<QueryDeliverCountryInfo> loadCountryList = baseMapper.countLoadCountryList(rq);
            if (CollectionUtil.isNotEmpty(loadCountryList)){
                if (loadCountryList.size() > 10){
                    List<QueryDeliverCountryInfo> ruletList = loadCountryList.stream().limit(10).collect(Collectors.toList());
                    QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
                    queryDeliverCountryInfo.setCountryName("others");
                    Integer total = 0;
                    for (int i = 10; i < loadCountryList.size(); i++) {
                        total = total + loadCountryList.get(i).getTotalCargoProspect();
                    }
                    queryDeliverCountryInfo.setTotalCargoProspect(total);
                    ruletList.add(queryDeliverCountryInfo);
                    queryReceiveCountryInfo.setDeliverCountryList(ruletList);
                }else {
                    queryReceiveCountryInfo.setDeliverCountryList(loadCountryList);
                }
            }
            //统计收货国
            List<QueryDeliverCountryInfo> dischargeCountryList = baseMapper.countDischargeCountryList(rq);
            if (CollectionUtil.isNotEmpty(dischargeCountryList)){
                if (dischargeCountryList.size() > 10){
                    List<QueryDeliverCountryInfo> ruletList = dischargeCountryList.stream().limit(10).collect(Collectors.toList());
                    QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
                    queryDeliverCountryInfo.setCountryName("others");
                    Integer total = 0;
                    for (int i = 10; i < dischargeCountryList.size(); i++) {
                        total = total + dischargeCountryList.get(i).getTotalCargoProspect();
                    }
                    queryDeliverCountryInfo.setTotalCargoProspect(total);
                    ruletList.add(queryDeliverCountryInfo);
                    queryReceiveCountryInfo.setVoyageCountryList(ruletList);
                }else {
                    queryReceiveCountryInfo.setVoyageCountryList(dischargeCountryList);
                }
            }
        }
//        List<QueryBoatsVoyageMessageInfo> boatsVoyageMessageList = baseMapper.queryBoatsVoyageList(rq);

        //计算贸易统计量
//        List<String> list = boatsVoyageMessageList.stream().map(QueryBoatsVoyageMessageInfo :: getStatisticalFilteringTime).collect(Collectors.toList());
//        List<String> timeList = list.stream().distinct().collect(Collectors.toList());
//        Map<String, List<QueryBoatsVoyageMessageInfo>> map = boatsVoyageMessageList.stream().collect(Collectors.groupingBy(QueryBoatsVoyageMessageInfo::getStatisticalFilteringTime));
//        if (CollectionUtil.isNotEmpty(timeList)){
//            List<QueryVolumeTradeIfo> volumeTradeList = new ArrayList<>();
//            timeList.forEach(item -> {
//                QueryVolumeTradeIfo queryVolumeTradeIfo = new QueryVolumeTradeIfo();
//                queryVolumeTradeIfo.setDate(item);
//                Integer number = 0;
//                if (CollectionUtil.isNotEmpty(map.get(item))){
//                    for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : map.get(item)) {
//                        if (queryBoatsVoyageMessageInfo.getTotalCargoProspect() != null) {
//                            number = number + Integer.decode(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
//                        }
//                    }
//                }
//                queryVolumeTradeIfo.setVolumeNumber(number);
//                volumeTradeList.add(queryVolumeTradeIfo);
//            });
//            List<QueryVolumeTradeIfo> tradeIfoList = volumeTradeList.stream().sorted(Comparator.comparing(QueryVolumeTradeIfo::getDate)).collect(Collectors.toList());
//            queryReceiveCountryInfo.setVolumeTradeList(tradeIfoList);
//        }

//        List<String> list1 = boatsVoyageMessageList.stream().filter(voyage -> StringUtils.isNotEmpty(voyage.getLoadCountry())).map(QueryBoatsVoyageMessageInfo::getLoadCountry).collect(Collectors.toList());
//        List<String> loadCountryList = list1.stream().distinct().collect(Collectors.toList());
//        if (CollectionUtil.isNotEmpty(loadCountryList)) {
//            List<QueryDeliverCountryInfo> deliverCountryList = new ArrayList<>();
//            Map<String, List<QueryBoatsVoyageMessageInfo>> loadCountryMap = boatsVoyageMessageList.stream().collect(Collectors.groupingBy(QueryBoatsVoyageMessageInfo::getLoadCountry));
//            loadCountryList.forEach(item -> {
//                QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
//                queryDeliverCountryInfo.setCountryName(item);
//                Integer number = 0;
//                if (CollectionUtil.isNotEmpty(loadCountryMap.get(item))) {
//                    for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : loadCountryMap.get(item)) {
//                        number = number + Integer.decode(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
//                    }
//                }
//                queryDeliverCountryInfo.setTotalCargoProspect(number);
//                deliverCountryList.add(queryDeliverCountryInfo);
//            });
//            if (CollectionUtil.isNotEmpty(deliverCountryList)) {
//                List<QueryDeliverCountryInfo> list = deliverCountryList.stream().sorted(Comparator.comparing(QueryDeliverCountryInfo::getTotalCargoProspect).reversed()).collect(Collectors.toList());
//                if (list.size() > 10){
//                    List<QueryDeliverCountryInfo> ruletList = list.stream().limit(10).collect(Collectors.toList());
//                    QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
//                    queryDeliverCountryInfo.setCountryName("others");
//                    Integer total = 0;
//                    for (int i = 10; i < deliverCountryList.size(); i++) {
//                        total = total + deliverCountryList.get(i).getTotalCargoProspect();
//                    }
//                    queryDeliverCountryInfo.setTotalCargoProspect(total);
//                    ruletList.add(queryDeliverCountryInfo);
//                    queryReceiveCountryInfo.setDeliverCountryList(ruletList);
//                }else {
//                    queryReceiveCountryInfo.setDeliverCountryList(list);
//                }
//            }
//        }
//        List<String> list2 = boatsVoyageMessageList.stream().filter(voyage -> StringUtils.isNotEmpty(voyage.getDischargeCountry())).map(QueryBoatsVoyageMessageInfo::getDischargeCountry).collect(Collectors.toList());
//        List<String> dischargeCountryList = list2.stream().distinct().collect(Collectors.toList());
//        if (CollectionUtil.isNotEmpty(dischargeCountryList)) {
//            Map<String, List<QueryBoatsVoyageMessageInfo>> dischargeCountryMap = boatsVoyageMessageList.stream().collect(Collectors.groupingBy(QueryBoatsVoyageMessageInfo::getDischargeCountry));
//            List<QueryDeliverCountryInfo> voyageCountryList = new ArrayList<>();
//            dischargeCountryList.forEach(item -> {
//                QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
//                queryDeliverCountryInfo.setCountryName(item);
//                Integer number = 0;
//                if (CollectionUtil.isNotEmpty(dischargeCountryMap.get(item))) {
//                    for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : dischargeCountryMap.get(item)) {
//                        number = number + Integer.decode(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
//                    }
//                }
//                queryDeliverCountryInfo.setTotalCargoProspect(number);
//                voyageCountryList.add(queryDeliverCountryInfo);
//            });
//
//            if (CollectionUtil.isNotEmpty(voyageCountryList)) {
//                List<QueryDeliverCountryInfo> list = voyageCountryList.stream().sorted(Comparator.comparing(QueryDeliverCountryInfo::getTotalCargoProspect).reversed()).collect(Collectors.toList());
//                if (voyageCountryList.size() > 10) {
//                    List<QueryDeliverCountryInfo> ruletList = list.stream().limit(10).collect(Collectors.toList());
//                    QueryDeliverCountryInfo queryDeliverCountryInfo = new QueryDeliverCountryInfo();
//                    queryDeliverCountryInfo.setCountryName("others");
//                    Integer total = 0;
//                    for (int i = 10; i < voyageCountryList.size(); i++) {
//                        total = total + voyageCountryList.get(i).getTotalCargoProspect();
//                    }
//                    queryDeliverCountryInfo.setTotalCargoProspect(total);
//                    ruletList.add(queryDeliverCountryInfo);
//                    queryReceiveCountryInfo.setVoyageCountryList(ruletList);
//                }else {
//                    queryReceiveCountryInfo.setVoyageCountryList(list);
//                }
//            }
//        }
        return queryReceiveCountryInfo;
    }

    public static Map<String, List<QueryVoyageTradeInfo>> groupByWeekNew(List<QueryVoyageTradeInfo> dates) {
        Map<String, List<QueryVoyageTradeInfo>> weeklyData = new HashMap<>();
        for (QueryVoyageTradeInfo date : dates) {
            if (null != date.getDate()){
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(DateUtil.parse(date.getDate(),DatePattern.NORM_DATE_FORMATTER));
                // 设置每周的开始日为周一
                calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                weeklyData.computeIfAbsent(DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_FORMATTER), k -> new ArrayList<>()).add(date);
            }
        }
        return weeklyData;
    }

    @Override
    public List<QueryVoyageTradeInfo> queryVolumeTrade(QueryBoatsVoyageRq rq) throws IllegalAccessException {
        List<QueryVoyageTradeInfo> volumeTradeList = new ArrayList<>();
        List<QueryVoyageTradeInfo> exportVolumeList = baseMapper.queryExportVolume(rq);
        List<QueryVoyageTradeInfo> importVolumeList = baseMapper.queryImportVolume(rq);
        List<String> dataList = new ArrayList<>();
        if (!"0".equals(rq.getDistinguishType())) {
            List<QueryVoyageTradeInfo> nowExportVolumeList = new ArrayList<>();
            List<QueryVoyageTradeInfo> nowImportVolumeList = new ArrayList<>();
            if ("1".equals(rq.getDistinguishType())) {
                Map<String, List<QueryVoyageTradeInfo>> exportVolumeMap = groupByWeekNew(exportVolumeList);
                if (CollectionUtil.isNotEmpty(exportVolumeMap)) {
                    exportVolumeMap.forEach((k, v) -> {
                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
                        dataList.add(k);
                        info.setDate(k);
                        BigDecimal number = new BigDecimal(0);
                        if (CollectionUtil.isNotEmpty(exportVolumeMap.get(k))) {
                            for (QueryVoyageTradeInfo voyageTradeInfo : exportVolumeMap.get(k)) {
                                number = number.add(voyageTradeInfo.getExportVolume());
                            }
                        }
                        info.setExportVolume(number);
                        nowExportVolumeList.add(info);
                    });
                }
                Map<String, List<QueryVoyageTradeInfo>> importVolumeMap = groupByWeekNew(importVolumeList);
                if (CollectionUtil.isNotEmpty(importVolumeMap)) {
                    importVolumeMap.forEach((key, value) -> {
                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
                        dataList.add(key);
                        info.setDate(key);
                        BigDecimal number = new BigDecimal(0);
                        if (CollectionUtil.isNotEmpty(importVolumeMap.get(key))) {
                            for (QueryVoyageTradeInfo voyageTradeInfo : importVolumeMap.get(key)) {
                                number = number.add(voyageTradeInfo.getImportVolume());
                            }
                        }
                        info.setImportVolume(number);
                        nowImportVolumeList.add(info);
                    });
                }
                if (CollectionUtil.isNotEmpty(dataList)) {
                    List<String> list = dataList.stream().distinct().collect(Collectors.toList());
                    List<String> list1 = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
                    Map<String, List<QueryVoyageTradeInfo>> nowExportVolumeMap = nowExportVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    Map<String, List<QueryVoyageTradeInfo>> nowImportVolumeMap = nowImportVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    list1.forEach(item -> {
                        QueryVoyageTradeInfo queryVoyageTradeInfo = new QueryVoyageTradeInfo();
                        queryVoyageTradeInfo.setDate(item);
                        if (CollectionUtil.isNotEmpty(nowExportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setExportVolume(nowExportVolumeMap.get(item).get(0).getExportVolume());
                        }else {
                            queryVoyageTradeInfo.setExportVolume(new BigDecimal(0));
                        }
                        if (CollectionUtil.isNotEmpty(nowImportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setImportVolume(nowImportVolumeMap.get(item).get(0).getImportVolume());
                        }else {
                            queryVoyageTradeInfo.setImportVolume(new BigDecimal(0));
                        }
                        volumeTradeList.add(queryVoyageTradeInfo);
                    });
                }
                return volumeTradeList;
            } else if ("2".equals(rq.getDistinguishType())) {
//                Map<DateTime, List<QueryVoyageTradeInfo>> exportVolumeMap = exportVolumeList.stream().collect(Collectors.groupingBy(item -> DateUtil.parse(item.getDate(), DatePattern.NORM_MONTH_FORMAT)));
//                if (CollectionUtil.isNotEmpty(exportVolumeMap)) {
//                    exportVolumeMap.forEach((k, v) -> {
//                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
//                        info.setDate(DateUtil.format(k, DatePattern.NORM_MONTH_FORMAT));
//                        dataList.add(DateUtil.format(k, DatePattern.NORM_MONTH_FORMAT));
//                        BigDecimal number = new BigDecimal(0);
//                        if (CollectionUtil.isNotEmpty(v)) {
//                            for (QueryVoyageTradeInfo voyageTradeInfo : v) {
//                                number = number.add(voyageTradeInfo.getExportVolume());
//                            }
//                        }
//                        info.setExportVolume(number);
//                        nowExportVolumeList.add(info);
//                    });
//                }
//                Map<DateTime, List<QueryVoyageTradeInfo>> importVolumeMap = importVolumeList.stream().collect(Collectors.groupingBy(item -> DateUtil.parse(item.getDate(), DatePattern.NORM_MONTH_FORMAT)));
//                if (CollectionUtil.isNotEmpty(importVolumeMap)) {
//                    importVolumeMap.forEach((key, value) -> {
//                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
//                        info.setDate(DateUtil.format(key, DatePattern.NORM_MONTH_FORMAT));
//                        dataList.add(DateUtil.format(key, DatePattern.NORM_MONTH_FORMAT));
//                        BigDecimal number = new BigDecimal(0);
//                        if (CollectionUtil.isNotEmpty(value)) {
//                            for (QueryVoyageTradeInfo voyageTradeInfo :value) {
//                                number = number.add(voyageTradeInfo.getImportVolume());
//                            }
//                        }
//                        info.setImportVolume(number);
//                        nowImportVolumeList.add(info);
//                    });
//                }
                List<QueryVoyageTradeInfo> exportVolumeMonthList = baseMapper.queryExportVolumeMonth(rq);
                if (CollectionUtil.isNotEmpty(exportVolumeMonthList)){
                    List<String> list = exportVolumeMonthList.stream().map(QueryVoyageTradeInfo::getDate).collect(Collectors.toList());
                    dataList.addAll(list);
                }
                List<QueryVoyageTradeInfo> importVolumeMonthList = baseMapper.queryImportVolumeMonth(rq);
                if (CollectionUtil.isNotEmpty(importVolumeMonthList)){
                    List<String> list = importVolumeMonthList.stream().map(QueryVoyageTradeInfo::getDate).collect(Collectors.toList());
                    dataList.addAll(list);
                }

                if (CollectionUtil.isNotEmpty(dataList)) {
                    List<String> list = dataList.stream().distinct().collect(Collectors.toList());
                    List<String> list1 = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
                    Map<String, List<QueryVoyageTradeInfo>> nowExportVolumeMap = exportVolumeMonthList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    Map<String, List<QueryVoyageTradeInfo>> nowImportVolumeMap = importVolumeMonthList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    list1.forEach(item -> {
                        QueryVoyageTradeInfo queryVoyageTradeInfo = new QueryVoyageTradeInfo();
                        queryVoyageTradeInfo.setDate(item);
                        if (CollectionUtil.isNotEmpty(nowExportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setExportVolume(nowExportVolumeMap.get(item).get(0).getExportVolume());
                        }else {
                            queryVoyageTradeInfo.setExportVolume(new BigDecimal(0));
                        }
                        if (CollectionUtil.isNotEmpty(nowImportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setImportVolume(nowImportVolumeMap.get(item).get(0).getImportVolume());
                        }else {
                            queryVoyageTradeInfo.setImportVolume(new BigDecimal(0));
                        }

                        volumeTradeList.add(queryVoyageTradeInfo);
                    });
                }
                return volumeTradeList;
            } else if ("3".equals(rq.getDistinguishType())) {
                Map<String, List<QueryVoyageTradeInfo>> exportVolumeMap = exportVolumeList.stream().collect(Collectors.groupingBy(item -> DateUtil.format(DateUtil.parse(item.getDate(), DatePattern.NORM_YEAR_PATTERN),DatePattern.NORM_YEAR_PATTERN)));
                if (CollectionUtil.isNotEmpty(exportVolumeMap)) {
                    exportVolumeMap.forEach((k, v) -> {
                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
                        info.setDate(k);
                        dataList.add(k);
                        BigDecimal number = new BigDecimal(0);
                        if (CollectionUtil.isNotEmpty(exportVolumeMap.get(k))) {
                            for (QueryVoyageTradeInfo voyageTradeInfo : exportVolumeMap.get(k)) {
                                number = number.add(voyageTradeInfo.getExportVolume());
                            }
                        }
                        info.setExportVolume(number);
                        nowExportVolumeList.add(info);
                    });
                }
                Map<String, List<QueryVoyageTradeInfo>> importVolumeMap = importVolumeList.stream().collect(Collectors.groupingBy(item -> DateUtil.format(DateUtil.parse(item.getDate(), DatePattern.NORM_YEAR_PATTERN),DatePattern.NORM_YEAR_PATTERN)));
                if (CollectionUtil.isNotEmpty(importVolumeMap)) {
                    importVolumeMap.forEach((key, value) -> {
                        QueryVoyageTradeInfo info = new QueryVoyageTradeInfo();
                        info.setDate(key);
                        dataList.add(key);
                        BigDecimal number = new BigDecimal(0);
                        if (CollectionUtil.isNotEmpty(importVolumeMap.get(key))) {
                            for (QueryVoyageTradeInfo voyageTradeInfo : importVolumeMap.get(key)) {
                                number = number.add(voyageTradeInfo.getImportVolume());
                            }
                        }
                        info.setImportVolume(number);
                        nowImportVolumeList.add(info);
                    });
                }
                if (CollectionUtil.isNotEmpty(dataList)) {
                    List<String> list = dataList.stream().distinct().collect(Collectors.toList());
                    List<String> list1 = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
                    Map<String, List<QueryVoyageTradeInfo>> nowExportVolumeMap = nowExportVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    Map<String, List<QueryVoyageTradeInfo>> nowImportVolumeMap = nowImportVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    list1.forEach(item -> {
                        QueryVoyageTradeInfo queryVoyageTradeInfo = new QueryVoyageTradeInfo();
                        queryVoyageTradeInfo.setDate(item);
                        if (CollectionUtil.isNotEmpty(nowExportVolumeMap.get(item))){
                            List<QueryVoyageTradeInfo> queryVoyageTradeInfos = nowExportVolumeMap.get(item);
                            queryVoyageTradeInfo.setExportVolume(nowExportVolumeMap.get(item).get(0).getExportVolume());
                        }else {
                            queryVoyageTradeInfo.setExportVolume(new BigDecimal(0));
                        }
                        if (CollectionUtil.isNotEmpty(nowImportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setImportVolume(nowImportVolumeMap.get(item).get(0).getImportVolume());
                        }else {
                            queryVoyageTradeInfo.setImportVolume(new BigDecimal(0));
                        }
                        volumeTradeList.add(queryVoyageTradeInfo);
                    });
                }
                return volumeTradeList;
            }
        }else {
            boolean status = this.checkDataStatus(rq);
            List<QueryVoyageTradeInfo> voyageTradeInfos = redisService.getCacheObject(CacheConstants.VOYAGE_LIST+"voyageTradeInfos");
            if (CollectionUtil.isNotEmpty(voyageTradeInfos)){
                return voyageTradeInfos;
            }else {
                if (CollectionUtil.isNotEmpty(exportVolumeList)){
                    List<String> list = exportVolumeList.stream().map(QueryVoyageTradeInfo::getDate).collect(Collectors.toList());
                    dataList.addAll(list);
                }
                if (CollectionUtil.isNotEmpty(importVolumeList)){
                    List<String> list = importVolumeList.stream().map(QueryVoyageTradeInfo::getDate).collect(Collectors.toList());
                    dataList.addAll(list);
                }
                if (CollectionUtil.isNotEmpty(dataList)) {
                    List<String> list = dataList.stream().distinct().collect(Collectors.toList());
                    List<String> list1 = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
                    Map<String, List<QueryVoyageTradeInfo>> exportVolumeMap = exportVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    Map<String, List<QueryVoyageTradeInfo>> importVolumeMap = importVolumeList.stream().collect(Collectors.groupingBy(QueryVoyageTradeInfo::getDate));
                    list1.forEach(item -> {
                        QueryVoyageTradeInfo queryVoyageTradeInfo = new QueryVoyageTradeInfo();
                        queryVoyageTradeInfo.setDate(item);
                        if (CollectionUtil.isNotEmpty(exportVolumeMap.get(item))){
                            queryVoyageTradeInfo.setExportVolume(exportVolumeMap.get(item).get(0).getExportVolume());
                        }else {
                            queryVoyageTradeInfo.setExportVolume(new BigDecimal(0));
                        }
                        if (CollectionUtil.isNotEmpty(importVolumeMap.get(item))){
                            queryVoyageTradeInfo.setImportVolume(importVolumeMap.get(item).get(0).getImportVolume());
                        }else {
                            queryVoyageTradeInfo.setImportVolume(new BigDecimal(0));
                        }

                        volumeTradeList.add(queryVoyageTradeInfo);
                    });
                }
                //刷新缓存信息
                redisService.setCacheObject(CacheConstants.VOYAGE_LIST+"voyageTradeInfos"
                        ,volumeTradeList,CacheConstants.DATA_BOARD_REFRESH_TIME, TimeUnit.MINUTES);
                return volumeTradeList;
            }
        }
        if (CollectionUtil.isNotEmpty(volumeTradeList)) {
            List<QueryVoyageTradeInfo> returnList = volumeTradeList.stream().sorted(Comparator.comparing(QueryVoyageTradeInfo::getDate)).collect(Collectors.toList());
            return returnList;
        }
        return volumeTradeList;
    }


    @Override
    public List<String> queryBoatsVoyageConditions(String type) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("enable", "1");
        List<SpBoatsVoyageMessage> boatsVoyageList = baseMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(boatsVoyageList)) {
            List<String> shipVoyageList = null;
            if ("shipName".equals(type)) {
                shipVoyageList = baseMapper.queryShipNameList();
            } else if ("imo".equals(type)) {
                shipVoyageList = boatsVoyageList.stream().map(SpBoatsVoyageMessage::getImo).collect(Collectors.toList());
            } else if ("loadCountry".equals(type)) {
                shipVoyageList = boatsVoyageList.stream().map(SpBoatsVoyageMessage::getLoadCountry).collect(Collectors.toList());
            } else if ("dischargeCountry".equals(type)) {
                shipVoyageList = boatsVoyageList.stream().map(SpBoatsVoyageMessage::getDischargeCountry).collect(Collectors.toList());
            } else if ("shipTypeGroup".equals(type)) {
                shipVoyageList = boatsArchivesService.queryShipTypeGroup();
            }
            List<String> returnList = shipVoyageList.stream().distinct().collect(Collectors.toList());
            return returnList;
        }
        return null;
    }

    @Override
    public QueryBoatsPortInfo queryPortNameByCountry(QueryPortNameRq rq) {
        QueryBoatsPortInfo queryBoatsPortInfo = new QueryBoatsPortInfo();
        if ("0".equals(rq.getQueryType())) {
            List<String> loadPortList = baseMapper.queryloadPortList(rq.getCountryNameList());
            List<String> list = loadPortList.stream().distinct().collect(Collectors.toList());
            queryBoatsPortInfo.setLoadPortList(list);
        } else if ("1".equals(rq.getQueryType())) {
            List<String> dischargePortList = baseMapper.queryDischargePort(rq.getCountryNameList());
            List<String> list = dischargePortList.stream().distinct().collect(Collectors.toList());
            queryBoatsPortInfo.setDischargePortList(list);
        }

        return queryBoatsPortInfo;
    }

    @Override
    public List<QueryBoatsVoyageMessageInfo> exportBoatsVoyage(QueryBoatsVoyageRq rq) {
        List<QueryBoatsVoyageMessageInfo> boatsVoyageMessageList = baseMapper.queryBoatsVoyageList(rq);
        return boatsVoyageMessageList;
    }

    public static Map<String, List<QueryBoatsVoyageMessageInfo>> groupByWeek(List<QueryBoatsVoyageMessageInfo> dates) {
        Map<String, List<QueryBoatsVoyageMessageInfo>> weeklyData = new HashMap<>();
        for (QueryBoatsVoyageMessageInfo date : dates) {
            if (null != date.getLoadInportTime()){
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(DateUtil.parse(date.getLoadInportTime(),DatePattern.NORM_DATETIME_FORMATTER));
                // 设置每周的开始日为周一
                calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                weeklyData.computeIfAbsent(DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_FORMATTER), k -> new ArrayList<>()).add(date);
            }
        }
        return weeklyData;
    }

    @Override
    public List<QueryVolumeTradeIfo> queryDistinguishType(QueryBoatsVoyageRq rq) {
        List<QueryVolumeTradeIfo> volumeTradeList = new ArrayList<>();
        if (!"0".equals(rq.getDistinguishType())) {
            List<QueryBoatsVoyageMessageInfo> boatsVoyageMessageList = baseMapper.queryBoatsVoyageList(rq);
            if ("1".equals(rq.getDistinguishType())) {
                Map<String, List<QueryBoatsVoyageMessageInfo>> map = groupByWeek(boatsVoyageMessageList);
                if (CollectionUtil.isNotEmpty(map)) {
                    map.forEach((k, v) -> {
                        QueryVolumeTradeIfo queryVolumeTradeIfo = new QueryVolumeTradeIfo();
                        queryVolumeTradeIfo.setDate(k);
                        Integer number = 0;
                        if (CollectionUtil.isNotEmpty(map.get(k))) {
                            for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : map.get(k)) {
                                number = number + Integer.parseInt(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
                            }
                        }
                        queryVolumeTradeIfo.setVolumeNumber(number);
                        volumeTradeList.add(queryVolumeTradeIfo);
                    });
                }
            } else if ("2".equals(rq.getDistinguishType())) {
                List<QueryBoatsVoyageMessageInfo> list = boatsVoyageMessageList.stream().filter(voyageMessage -> voyageMessage.getLoadInportTime() != null).collect(Collectors.toList());
                Map<DateTime, List<QueryBoatsVoyageMessageInfo>> map = list.stream().collect(Collectors.groupingBy(item -> DateUtil.parse(item.getLoadInportTime(), DatePattern.NORM_MONTH_FORMAT)));
//                Map<String, List<QueryBoatsVoyageMessageInfo>> map = boatsVoyageMessageList.stream().filter(voyageMessage -> voyageMessage.getLoadInportTime() != null)
//                        .collect(Collectors.groupingBy(item -> new SimpleDateFormat("yyyy-MM").format(item.getLoadInportTime())));
                if (CollectionUtil.isNotEmpty(map)) {
                    map.forEach((k, v) -> {
                        QueryVolumeTradeIfo queryVolumeTradeIfo = new QueryVolumeTradeIfo();
                        queryVolumeTradeIfo.setDate(DateUtil.format(k,DatePattern.NORM_MONTH_FORMAT));
                        Integer number = 0;
                        if (CollectionUtil.isNotEmpty(map.get(k))) {
                            for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : map.get(k)) {
                                number = number + Integer.parseInt(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
                            }
                        }
                        queryVolumeTradeIfo.setVolumeNumber(number);
                        volumeTradeList.add(queryVolumeTradeIfo);
                    });
                }
            } else if ("3".equals(rq.getDistinguishType())) {
                List<QueryBoatsVoyageMessageInfo> list = boatsVoyageMessageList.stream().filter(voyageMessage -> voyageMessage.getLoadInportTime() != null).collect(Collectors.toList());
                Map<DateTime, List<QueryBoatsVoyageMessageInfo>> map = list.stream().collect(Collectors.groupingBy(item -> DateUtil.parse(item.getLoadInportTime(), DatePattern.NORM_YEAR_PATTERN)));
//                Map<String, List<QueryBoatsVoyageMessageInfo>> map = boatsVoyageMessageList.stream().filter(voyageMessage -> voyageMessage.getLoadInportTime() != null).collect(Collectors.groupingBy(item -> new SimpleDateFormat("yyyy").format(item.getLoadInportTime())));
                if (CollectionUtil.isNotEmpty(map)) {
                    map.forEach((k, v) -> {
                        QueryVolumeTradeIfo queryVolumeTradeIfo = new QueryVolumeTradeIfo();
                        queryVolumeTradeIfo.setDate(DateUtil.format(k,DatePattern.NORM_YEAR_PATTERN));
                        Integer number = 0;
                        if (CollectionUtil.isNotEmpty(map.get(k))) {
                            for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : map.get(k)) {
                                number = number + Integer.parseInt(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
                            }
                        }
                        queryVolumeTradeIfo.setVolumeNumber(number);
                        volumeTradeList.add(queryVolumeTradeIfo);
                    });
                }
            }
        } else {
//                Map<String, List<QueryBoatsVoyageMessageInfo>> map = boatsVoyageMessageList.stream().collect(Collectors.groupingBy(item -> new SimpleDateFormat("yyyy-MM-dd").format(item.getLoadInportTime())));
//                if (CollectionUtil.isNotEmpty(map)) {
//                    map.forEach((k, v) -> {
//                        QueryVolumeTradeIfo queryVolumeTradeIfo = new QueryVolumeTradeIfo();
//                        queryVolumeTradeIfo.setDate(k);
//                        Integer number = 0;
//                        if (CollectionUtil.isNotEmpty(map.get(k))) {
//                            for (QueryBoatsVoyageMessageInfo queryBoatsVoyageMessageInfo : map.get(k)) {
//                                number = number + Integer.parseInt(queryBoatsVoyageMessageInfo.getTotalCargoProspect());
//                            }
//                        }
//                        queryVolumeTradeIfo.setVolumeNumber(number);
//                        volumeTradeList.add(queryVolumeTradeIfo);
//                    });
//                }
//            }
//            return volumeTradeList.stream().sorted(Comparator.comparing(QueryVolumeTradeIfo::getDate)).collect(Collectors.toList());
            return baseMapper.queryVolumeTrade(rq);
        }
        if (CollectionUtil.isNotEmpty(volumeTradeList)) {
            List<QueryVolumeTradeIfo> returnList = volumeTradeList.stream().sorted(Comparator.comparing(QueryVolumeTradeIfo::getDate)).collect(Collectors.toList());
            return returnList;
        }
        return volumeTradeList;
    }
}
